package com.spa.domain.service;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.collect.Lists;
import com.spa.application.command.member.MemberOrderAddCommand;
import com.spa.application.command.member.MemberOrderExtAddCommand;
import com.spa.domain.entity.*;
import com.spa.infrastructure.enums.dict.base.WhetherTypeEnum;
import com.spa.infrastructure.enums.dict.order.OrderIsTransferEnum;
import com.spa.infrastructure.enums.dict.order.OrderStatusEnum;
import com.spa.infrastructure.enums.dict.order.OrderTransferStatusEnum;
import com.spa.infrastructure.mapper.MassageServiceMapperStruct;
import com.spa.infrastructure.mapper.OrderClientMapperStruct;
import com.spa.infrastructure.mapper.OrderExtMapperStruct;
import com.spa.infrastructure.mapper.OrderMapperStruct;
import com.spa.infrastructure.repository.condition.*;
import com.spa.infrastructure.repository.po.*;
import com.spa.infrastructure.repository.service.*;
import com.spa.infrastructure.service.gaode.GaodeService;
import com.spa.infrastructure.util.FeeUtil;
import com.spa.infrastructure.util.OrderUtils;
import com.spa.infrastructure.util.RedisKeyUtil;
import com.spa.infrastructure.util.RedisUtil;
import com.spa.infrastructure.util.SessionUtil;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 此类对外提供订单服务相关的所有接口
 * 以下方法区分 对外和对内使用
 */
@Service
@Slf4j
public class OrderService {

    @Resource
    private OrderInfoRepositoryService repositoryService;

    @Autowired
    private OrderDetailRepositoryService orderDetailRepositoryService;

    @Autowired
    private OrderExtDetailRepositoryService orderExtDetailRepositoryService;

    @Resource
    private GaodeService gaodeService;

    @Resource
    private OrderInfoExtRepositoryService orderExtRepositoryService;

    @Resource
    private MassageService massageService;

    @Resource
    private UserTicketService userTicketService;

    @Autowired
    private ShopService shopService;

    @Autowired
    private UserInfoService userInfoService;

    @Resource
    private MassagistService massagistService;

    @Resource
    private MassagistEvaluateService massagistEvaluateService;

    @Resource
    private FeeUtil feeUtil;

    @Autowired
    private RedisUtil redisUtil;

    @Autowired
    private ProfitService profitService;

    @Autowired
    private RefundDomainService refumdService;

    @Autowired
    private OrderTransferService orderTransferService;

    @Resource
    private TradeService tradeService;

    /**
     * 根据条件判断订单是否存在
     * @param condition
     * @return
     */
    public boolean existsByCondition(OrderInfoCondition condition) {
        return repositoryService.orderExists(condition);
    }

    /**
     * 添加订单
     *
     * @author: lig
     * @date: 2023/12/9
     */
    @Transactional
    public long addOrderInfo(MemberOrderAddCommand command, Massagist massagist, UserAddress address) {
        OrderInfoPO po = OrderMapperStruct.INSTANCE.commandMember2Po(command);
        //用户信息
        long userId = SessionUtil.getUser().getExtUserId();
        UserInfo userInfo = userInfoService.userInfoById(userId);
        po.setUserId(userId);
        po.setUserName(userInfo.getName());
        po.setUserPhone(userInfo.getPhone());
        //门店信息
        Shop shop = shopService.getInfoById(massagist.getShopId());
        po.setShopId(shop.getId());
        po.setShopName(shop.getName());
        po.setShopPhone(shop.getPhone());
        //获取技师信息
        po.setMassagistName(massagist.getName());
        po.setMassagistPhone(massagist.getPhone());
        //服务项目信息
        MassageServiceEntity serviceEntity = massageService.infoById(command.getServiceId());
        po.setServiceName(serviceEntity.getName());
        //优惠券
        Integer couponPriceInt = ObjectUtil.isNull(command.getCouponId()) ? 0 :
                userTicketService.getCouponPrice(command.getCouponId());
        //使用了团购券，不能使用优惠券,更新团购券状态
        if (command.isUseCoupon()) {
            couponPriceInt = 0;
        }
        //距离
        BigDecimal distDouble = gaodeService.getDistance(massagist.getLon(), massagist.getLat(), address.getLon(),
                address.getLat());
        double travelPrice = feeUtil.calculateFee(distDouble, massagist.getShopId());
        po.setTravelPrice(Convert.toInt(travelPrice));
        po.setOrderPrice(Convert.toInt(OrderUtils.calcOrderTotal(serviceEntity.getDiscountPrice(),
                command.getServiceQuantity(), couponPriceInt, travelPrice)));
        po.setTravelDist(OrderUtils.gainDoubleDist(distDouble.doubleValue()).toString());
        //到期时间   创建时间加10分钟
        po.setExpiryTime(OrderUtils.toDate(LocalDateTime.now().plusMinutes(10)));//todo  此处的10分钟后续考虑走配置的方式
        po.setOrderCode(OrderUtils.generateOrderCode());
        po.setStatus(OrderStatusEnum.$10.getCode());
        if (repositoryService.insertOrder(po) > 0) {
            insertOrderDetail(po.getId(), massagist, address, serviceEntity);
        }
        return po.getId();
    }

    /**
     * 添加订单扩展信息
     *
     * @author: lig
     * @date: 2023/12/9
     */
    public long addOrderInfoExt(MemberOrderExtAddCommand command) {
        OrderExtPO extPo = OrderMapperStruct.INSTANCE.commandMember2ExtPo(command);
        //服务项目信息
        MassageServiceEntity serviceEntity = massageService.infoById(command.getServiceId());
        extPo.setOrderPrice(OrderUtils.calcOrderTotal(serviceEntity.getDiscountPrice(), command.getOrderCount(), null
                , null));
        extPo.setIsDel(WhetherTypeEnum.$1.getCode());
        extPo.setOrderCount(command.getOrderCount());
        extPo.setStartTime(new Date());
        extPo.setServiceName(serviceEntity.getName());
        extPo.setOrderExtCode(OrderUtils.generateExtOrderCode());
        orderExtRepositoryService.insertOrderExt(extPo);
        insertOrderExtDetail(extPo.getId(), serviceEntity);
        return extPo.getId();
    }

    /**
     * 取消订单
     *
     * @author: lig
     * @date: 2023/12/9
     */
    @Transactional
    public boolean cancelOrder(OrderInfo orderInfo) {
        OrderInfoPO po = new OrderInfoPO();
        po.setId(orderInfo.getId());
        po.setStatus(OrderStatusEnum.$99.getCode());
        po.setSubStatus(orderInfo.getSubStatus());
        po.setCancelReason(orderInfo.getCancelReason());
        po.setCancelTime(new Date());
        boolean ret = repositoryService.updateByCondition(po);
        // 待接单 订单 15分钟后没人接单，通知用户取消接单，只通知一次 取消之后清除Redis
        if (ret) {
            Boolean flag = redisUtil.hasKey(RedisKeyUtil.getNotificationUserKey(orderInfo.getOrderCode()));
            if (flag) {
                redisUtil.delete(RedisKeyUtil.getNotificationUserKey(orderInfo.getOrderCode()));
            }
        }
        return ret;
    }

    /**
     * 根据条件统计订单
     *
     * @return 订单数量
     */
    public Long countByCondition(OrderInfoCondition condition) {
        return repositoryService.countByCondition(condition);
    }

    public Long countDistinctUser4ByStatus(int status) {
        OrderInfoCondition condition = new OrderInfoCondition();
        condition.setStatus(status);
        return repositoryService.countByConditionDistinctUser(condition);
    }

    public List<OrderInfo> listGroupByUser(int status) {
        OrderInfoCondition condition = new OrderInfoCondition();
        condition.setStatus(status);
        return OrderMapperStruct.INSTANCE.po2Entity4List(repositoryService.listGroupByUser(condition));
    }

    /**
     * 根据技师ID分组统计
     * @param ids
     * @return
     */
    public List<Map<String, Object>> countByMassagistIds(List<Long> ids) {
        return repositoryService.countByMassagistIds(ids);
    }

    /**
     * 根据订单编号查询订单
     * @param orderCode
     * @return
     */
    public OrderInfo getOrderByCode(String orderCode) {
        OrderInfoCondition condition = new OrderInfoCondition();
        condition.setOrderNo(orderCode);
        return OrderMapperStruct.INSTANCE.po2Entity(repositoryService.getOrderInfoOne(condition));
    }

    /**
     * 根据加钟订单的订单编号查询加钟订单
     * @param condition
     * @return
     */
    public OrderExtPO infoExtOne(OrderExtCondition condition) {
        return orderExtRepositoryService.getOrderInfoOne(condition);
    }

    /**
     * 根据加钟ID查询加钟订单信息
     * @param extId
     * @return
     */
    public OrderExt infoExtOrderById(Long extId) {
        return OrderMapperStruct.INSTANCE.po2Entity(orderExtRepositoryService.getById(extId));
    }

    /**
     * 加钟订单支付成功，更新加钟订单为有效状态
     * @param extId
     * @param isDelEnum
     * @return
     */
    public boolean ExtOrderPaySuccess(Long extId, WhetherTypeEnum isDelEnum) {
        OrderExtPO po = new OrderExtPO();
        po.setId(extId);
        po.setIsDel(isDelEnum.getCode());
        return orderExtRepositoryService.updateByCondition(po);
    }

    /**
     * 根据订单id获取订单详情
     * lig add 2024-02-29
     *
     * @param orderId 订单id
     * @return 订单
     */
    public OrderInfo getOrderInfoById(Long orderId, OrderInfoPlug plug) {
        OrderInfo orderInfo = OrderMapperStruct.INSTANCE.po2Entity(repositoryService.getOrderInfoById(orderId));
        setOrderInfoPlug(Lists.newArrayList(orderInfo), plug);
        return orderInfo;
    }

    /**
     * 根据自定义的条件分页查询订单
     *
     * @param condition 自定义的条件
     * @return 订单集合
     */
    public Page<OrderInfo> pageByCondition(OrderInfoCondition condition, OrderInfoPlug plug) {
        Page<OrderInfo> page = OrderMapperStruct.INSTANCE.po2Entity4Page(repositoryService.page(condition));
        List<OrderInfo> orderInfos = page.getRecords();
        setOrderInfoPlug(orderInfos, plug);
        return page;
    }

    /**
     * 根据自定义条件查询订单列表
     * @param condition
     * @return
     */
    public List<OrderInfo> orderList(OrderInfoCondition condition) {
        List<OrderInfo> orderInfos = OrderMapperStruct.INSTANCE.po2Entity4List(repositoryService.list(condition));
        OrderInfoPlug plug = OrderInfoPlug.base();
        plug.setTicket(true);
        plug.setTrade(true);
        plug.setProfit(true);
        setOrderInfoPlug(orderInfos, plug);
        return orderInfos;
    }

    /**
     * 订单转单给调度员
     * @param orderInfo
     * @param createId
     * @param createName
     */
    public void orderTransfer(OrderInfo orderInfo, Long createId, String createName) {
        OrderInfoPO po = new OrderInfoPO();
        po.setId(orderInfo.getId());
        po.setIsTransfer(OrderIsTransferEnum.$1.getCode());
        if (updateOrder(po)) {
            OrderTransfer orderTransfer = new OrderTransfer();
            orderTransfer.setOrderId(orderInfo.getId());
            orderTransfer.setOrderCode(orderInfo.getOrderCode());
            orderTransfer.setServiceId(orderInfo.getServiceId());
            orderTransfer.setServiceName(orderInfo.getServiceName());
            orderTransfer.setAppointMassagistId(orderInfo.getMassagistId());
            orderTransfer.setAppointMassagistName(orderInfo.getMassagistName());
            orderTransfer.setAppointMassagistPhone(orderInfo.getMassagistPhone());
            orderTransfer.setShopId(orderInfo.getShopId());
            orderTransfer.setShopName(orderInfo.getShopName());
            orderTransfer.setStatus(OrderTransferStatusEnum.$10.getCode());
            orderTransfer.setAppointTime(orderInfo.getAppointTime());
            orderTransfer.setOrderCreateTime(orderInfo.getCreateTime());
            orderTransfer.setOperName(createName);
            orderTransfer.setOperData(new Date());
            //转为转单数据
            orderTransferService.add(orderTransfer, createId, createName, 1);
        }
    }

    /**
     * 订单转单给真实技师
     * @param orderInfo
     * @param createId
     * @param createName
     */
    public void orderTransfer2Massagist(OrderInfo orderInfo, Long createId, String createName, Massagist massagist) {
        OrderInfoPO po = new OrderInfoPO();
        po.setId(orderInfo.getId());
        po.setIsTransfer(OrderIsTransferEnum.$0.getCode());
        po.setMassagistId(massagist.getId());
        po.setMassagistName(massagist.getName());
        po.setMassagistPhone(massagist.getPhone());
        if (updateOrder(po)) {
            OrderTransfer orderTransfer = new OrderTransfer();
            orderTransfer.setOrderId(orderInfo.getId());
            orderTransfer.setOrderCode(orderInfo.getOrderCode());
            orderTransfer.setServiceId(orderInfo.getServiceId());
            orderTransfer.setServiceName(orderInfo.getServiceName());
            orderTransfer.setAppointMassagistId(orderInfo.getMassagistId());
            orderTransfer.setAppointMassagistName(orderInfo.getMassagistName());
            orderTransfer.setAppointMassagistPhone(orderInfo.getMassagistPhone());
            orderTransfer.setShopId(orderInfo.getShopId());
            orderTransfer.setShopName(orderInfo.getShopName());
            orderTransfer.setStatus(OrderTransferStatusEnum.$20.getCode());
            orderTransfer.setAppointTime(orderInfo.getAppointTime());
            orderTransfer.setOrderCreateTime(orderInfo.getCreateTime());
            orderTransfer.setServeMassagistId(massagist.getId());
            orderTransfer.setServeMassagistName(massagist.getName());
            orderTransfer.setServeMassagistPhone(massagist.getPhone());
            orderTransfer.setOperName(createName);
            orderTransfer.setOperData(new Date());
            //转为转单数据
            orderTransferService.add(orderTransfer, createId, createName, 0);
        }
    }

    /**
     * 调度员将订单转单给技师
     * @param orderId
     * @param massagist
     */
    public void orderTransfer2Massagist(Long orderId, Massagist massagist) {
        //流转为已转单
        OrderTransfer orderTransfer = new OrderTransfer();
        orderTransfer.setServeMassagistId(massagist.getId());
        orderTransfer.setServeMassagistName(massagist.getName());
        orderTransfer.setServeMassagistPhone(massagist.getPhone());
        orderTransfer.setOperName(SessionUtil.getUser().getShopUser().getName());
        orderTransfer.setOperData(new Date());
        orderTransfer.setStatus(OrderTransferStatusEnum.$20.getCode());
        if (orderTransferService.updateReceivByOrderId(orderTransfer, orderId, massagist.getId())) {
            //修改原订单技师信息
            OrderInfoPO po = new OrderInfoPO();
            po.setId(orderId);
            po.setMassagistId(massagist.getId());
            po.setMassagistName(massagist.getName());
            po.setMassagistPhone(massagist.getPhone());
            po.setIsTransfer(OrderIsTransferEnum.$0.getCode());
            updateOrder(po);
        }
    }

    /**
     * 根据ID更新指定字段
     * @param po
     */
    public boolean updateOrder(OrderInfoPO po) {
        return repositoryService.updateByCondition(po);
    }

    public void calculatePerformance() {
        List<OrderInfo> orderInfoList = orderList(new OrderInfoCondition());
    }

    /********************************************     以下方法不对外提供                *************************************************/

    /**
     * @description: 根据开关组装订单数据
     * @TODO 需要替换订单相关set方法
     * @author: lig
     * @date: 2024/3/7
     */
    private void setOrderInfoPlug(List<OrderInfo> orderInfos, OrderInfoPlug orderInfoPlug) {

        setDetail(orderInfos);
        if (orderInfoPlug.isOrderExt()) {
            setExt4OrderList(orderInfos);
        }
        if (orderInfoPlug.isTicket()) {
            setTicket4OrderList(orderInfos);
        }
        if (orderInfoPlug.isEvaluate()) {
            setEvaluateStatus4OrderList(orderInfos);
        }
        //分佣
        if (orderInfoPlug.isProfit()) {
            setProfit4OrderList(orderInfos);
        }
        //退款
        if (orderInfoPlug.isRefumd()) {
            setRefund4OrderList(orderInfos);
        }
        // 交易信息
        if(orderInfoPlug.isTrade()){
            setTrade4OrderList(orderInfos);
        }

        //目前使用的订单表中的数据
//        if (orderInfoPlug.isShop()) {
//            setShop4OrderList(orderInfos);
//        }
//        if (orderInfoPlug.isUserInfo()) {
//            setUserInfo4OrderList(orderInfos);
//        }
//        if (orderInfoPlug.isMassageService()) {
//            setMassageService4OrderList(orderInfos);
//        }
//        if (orderInfoPlug.isMassagist()) {
//            setMassagist4OrderList(orderInfos);
//        }
    }

    /**
     * 根据订单id获取加钟订单列表
     *
     * @param orderInfos 订单id集合
     * @return 加钟订单列表
     */
    private void setExt4OrderList(List<OrderInfo> orderInfos) {
        if (CollectionUtil.isEmpty(orderInfos)) {
            return;
        }
        List<Long> ids = orderInfos.stream().map(OrderInfo::getId).toList();
        List<OrderExt> orderExtList = getOrderExts(ids);
        Map<Long, List<OrderExt>> map = orderExtList.stream().collect(Collectors.groupingBy(OrderExt::getOrderId));
        //edit lig 2024-02-22 增加订单总金额赋值
        orderInfos.forEach(orderInfo -> {
            List<OrderExt> orderExts = map.get(orderInfo.getId());
            setMassageService4Ext(orderExts);
            orderInfo.setOrderExtList(orderExts);
            if (CollUtil.isNotEmpty(orderExts)) {
                orderInfo.setOrderTotalPrice(orderInfo.getOrderPrice() + orderExts.stream().map(e -> e.getOrderPrice()).reduce(Integer::sum).get());
            } else {
                orderInfo.setOrderTotalPrice(orderInfo.getOrderPrice());
            }
        });
    }

    private List<OrderExt> getOrderExts(List<Long> ids) {
        OrderExtCondition condition = new OrderExtCondition();
        condition.setOrderIds(ids);
        condition.setIsDel(WhetherTypeEnum.$0.getCode());
        return OrderExtMapperStruct.INSTANCE.po2Entity4List(orderExtRepositoryService.list(condition));
    }

    private void setShop4OrderList(List<OrderInfo> orderInfos) {
        if (CollectionUtil.isEmpty(orderInfos)) {
            return;
        }
        List<Long> ids = orderInfos.stream().map(OrderInfo::getShopId).toList();
        Map<Long, Shop> map = shopService.groupById(shopService.listShopByIds(ids));
        orderInfos.forEach(orderInfo -> orderInfo.setShop(map.get(orderInfo.getShopId())));
    }

    private void buildOrderAddress(OrderAddress oc) {
        if (ObjectUtil.isNotEmpty(oc)) {
            oc.setAddress(ObjectUtil.defaultIfNull(oc.getRegion(), "") + ObjectUtil.defaultIfNull(oc.getAddress(), ""));
        }
    }

    private void setTicket4OrderList(List<OrderInfo> orderInfos) {
        if (CollectionUtil.isEmpty(orderInfos)) {
            return;
        }
        List<Long> ids = orderInfos.stream().map(OrderInfo::getTicketId).toList();
        Map<Long, UserTicket> map = userTicketService.groupById(userTicketService.listTicketByIds(ids));
        orderInfos.forEach(orderInfo -> orderInfo.setTicket(map.get(orderInfo.getTicketId())));
    }

    private void setUserInfo4OrderList(List<OrderInfo> orderInfos) {
        if (CollectionUtil.isEmpty(orderInfos)) {
            return;
        }
        List<Long> ids = orderInfos.stream().map(OrderInfo::getUserId).toList();
        Map<Long, UserInfo> map = userInfoService.groupById(userInfoService.getUserListByIds(ids));
        orderInfos.forEach(orderInfo -> orderInfo.setUserInfo(map.get(orderInfo.getUserId())));
    }

    private void setMassageService4Ext(List<OrderExt> orderExts) {
        if (CollectionUtil.isEmpty(orderExts)) {
            return;
        }
        List<Long> ids = orderExts.stream().map(OrderExt::getId).toList();
        List<OrderExtDetailPO> pos = orderExtDetailRepositoryService.queryByOrderExtIds(ids);
        Map<Long, OrderExtDetailPO> map = pos.stream().collect(Collectors.toMap(OrderExtDetailPO::getOrderExtId, Function.identity()));
        orderExts.forEach(orderExt -> {
            MassageServiceEntity massageServiceEntity = MassageServiceMapperStruct.INSTANCE.po2Entity(map.get(orderExt.getId()));
            //服务项目信息
            if (ObjectUtil.isNotNull(massageServiceEntity)) {
                orderExt.setMassageServiceEntity(massageServiceEntity);
                orderExt.getMassageServiceEntity().setId(orderExt.getServiceId());
                orderExt.getMassageServiceEntity().setName(orderExt.getServiceName());
            }
        });
    }

    private void setMassageService4OrderList(List<OrderInfo> orderInfos) {
        if (CollectionUtil.isEmpty(orderInfos)) {
            return;
        }
        List<Long> ids = orderInfos.stream().map(OrderInfo::getServiceId).toList();
        Map<Long, MassageServiceEntity> map =
                massageService.list2Map(massageService.getMassageServiceEntityListByIds(ids));
        orderInfos.forEach(orderInfo -> orderInfo.setMassageService(map.get(orderInfo.getServiceId())));
    }

    private void setMassagist4OrderList(List<OrderInfo> orderInfos) {
        if (CollectionUtil.isEmpty(orderInfos)) {
            return;
        }
        List<Long> ids = orderInfos.stream().map(OrderInfo::getMassagistId).toList();
        Map<Long, Massagist> map = massagistService.groupById(massagistService.list(ids));
        orderInfos.forEach(orderInfo -> orderInfo.setMassagist(map.get(orderInfo.getMassagistId())));
    }

    /**
     * 设置评价状态
     *
     * @author: lig
     * @date: 2024/1/18
     */
    private void setEvaluateStatus4OrderList(List<OrderInfo> orderInfos) {
        if (CollectionUtil.isEmpty(orderInfos) || !StpUtil.isLogin()) {
            return;
        }
        orderInfos.stream().forEach(a -> {
            a.setHasComments(massagistEvaluateService.verifyEvaluate(a.getId(), SessionUtil.getUser().getUserId()));
        });
    }

    /**
     * 分佣
     *
     * @author: lig
     * @date: 2024/2/27
     */
    private void setProfit4OrderList(List<OrderInfo> orderInfos) {
        if (CollectionUtil.isEmpty(orderInfos)) {
            return;
        }
        List<Long> ids = orderInfos.stream().map(OrderInfo::getId).toList();
        List<Profit> profitList = profitService.queryProfitByOrderIds(ids);
        Map<Long, List<Profit>> map = profitList.stream().collect(Collectors.groupingBy(Profit::getOrderId));
        orderInfos.forEach(orderInfo -> orderInfo.setProfitList(map.get(orderInfo.getId())));
    }

    /**
     * 退款
     *
     * @author: lig
     * @date: 2024/2/27
     */
    private void setRefund4OrderList(List<OrderInfo> orderInfos) {
        if (CollectionUtil.isEmpty(orderInfos)) {
            return;
        }
        List<String> orderCodes = orderInfos.stream().map(OrderInfo::getOrderCode).toList();
        List<Refund> refundList = refumdService.queryRefundByOrderCodes(orderCodes);

        Map<String, Integer> map = refundList.stream().collect(Collectors.toMap(Refund::getOutTradeNo, Refund::getPayerRefund,
                Integer::sum));

        orderInfos.forEach(orderInfo -> orderInfo.setRefundTotalMoney(map.get(orderInfo.getOrderCode())));
    }

    /**
     * 给订单 赋值 地址信息 和 项目信息，信息来源于s_order_detail表
     * @param orderInfos
     */
    private void setDetail(List<OrderInfo> orderInfos) {
        if (CollectionUtil.isEmpty(orderInfos)) {
            return;
        }
        List<Long> ids = orderInfos.stream().map(OrderInfo::getId).toList();
        OrderDetailCondition condition = new OrderDetailCondition();
        condition.setOrderIds(ids);
        List<OrderDetailPO> pos = orderDetailRepositoryService.listInfo(condition);
        Map<Long, OrderDetailPO> map = pos.stream().collect(Collectors.toMap(OrderDetailPO::getOrderId, Function.identity()));
        orderInfos.forEach(orderInfo -> {
            OrderDetailPO po = map.get(orderInfo.getId());
            //地址信息
            orderInfo.setOrderAddress(OrderClientMapperStruct.INSTANCE.po2Entity(po));
            buildOrderAddress(orderInfo.getOrderAddress());
            //服务项目信息
            orderInfo.setMassageService(MassageServiceMapperStruct.INSTANCE.po2Entity(po));
            orderInfo.getMassageService().setId(orderInfo.getServiceId());
            orderInfo.getMassageService().setName(orderInfo.getServiceName());
        });
    }

    /**
     * 保存订单详情信息
     * @param id
     * @param massagist
     * @param address
     * @param serviceEntity
     */
    private void insertOrderDetail(Long id, Massagist massagist, UserAddress address, MassageServiceEntity serviceEntity) {
        OrderDetailPO orderDetail = new OrderDetailPO();
        orderDetail.setOrderId(id);
        orderDetail.setMassagistLon(massagist.getLon());
        orderDetail.setMassagistLat(massagist.getLat());
        orderDetail.setAddressName(address.getName());
        orderDetail.setAddressPhone(address.getPhone());
        orderDetail.setAddressRegion(address.getRegion());
        orderDetail.setAddressAddress(address.getAddress());
        orderDetail.setAddressLon(address.getLon());
        orderDetail.setAddressLat(address.getLat());
        orderDetail.setServiceSex(serviceEntity.getSex());
        orderDetail.setServiceRecommendations(serviceEntity.getRecommendations());
        orderDetail.setServiceDuration(serviceEntity.getDuration());
        orderDetail.setServiceHighlights(serviceEntity.getHighlights());
        orderDetail.setServiceHighlightsTar(serviceEntity.getHighlightsTar());
        orderDetail.setServiceImg(serviceEntity.getOldImg());
        orderDetail.setServiceCover(serviceEntity.getOldCover());
        orderDetail.setServiceNote(serviceEntity.getNote());
        orderDetail.setServiceDeclaration(serviceEntity.getDeclaration());
        orderDetail.setServicePrice(serviceEntity.getPrice());
        orderDetail.setServiceDiscountPrice(serviceEntity.getDiscountPrice());
        orderDetail.setServiceTargetGroup(serviceEntity.getTargetGroup());
        orderDetailRepositoryService.insert(orderDetail);
    }

    /**
     * 保存加钟订单的详情
     * @param id
     * @param serviceEntity
     */
    private void insertOrderExtDetail(Long id, MassageServiceEntity serviceEntity) {
        OrderExtDetailPO orderExtDetailPO = new OrderExtDetailPO();
        orderExtDetailPO.setOrderExtId(id);
        orderExtDetailPO.setServiceSex(serviceEntity.getSex());
        orderExtDetailPO.setServiceRecommendations(serviceEntity.getRecommendations());
        orderExtDetailPO.setServiceDuration(serviceEntity.getDuration());
        orderExtDetailPO.setServiceHighlights(serviceEntity.getHighlights());
        orderExtDetailPO.setServiceHighlightsTar(serviceEntity.getHighlightsTar());
        orderExtDetailPO.setServiceImg(serviceEntity.getOldImg());
        orderExtDetailPO.setServiceCover(serviceEntity.getOldCover());
        orderExtDetailPO.setServiceNote(serviceEntity.getNote());
        orderExtDetailPO.setServiceDeclaration(serviceEntity.getDeclaration());
        orderExtDetailPO.setServicePrice(serviceEntity.getPrice());
        orderExtDetailPO.setServiceDiscountPrice(serviceEntity.getDiscountPrice());
        orderExtDetailPO.setServiceTargetGroup(serviceEntity.getTargetGroup());
        orderExtDetailRepositoryService.insert(orderExtDetailPO);
    }

    /**
     * 根据订单信息列表设置交易信息。
     * @param orderInfos 订单信息列表，不应为空。列表中的每个订单信息对象需包含订单代码（orderCode）。
     */
    private void setTrade4OrderList(List<OrderInfo> orderInfos) {
        if (CollectionUtil.isEmpty(orderInfos)) {
            return;
        }
        List<String> orderCodes = orderInfos.stream().map(OrderInfo::getOrderCode).toList();
        List<Trade> tradeList = tradeService.list(orderCodes);
        Map<String, Trade> map = tradeList.stream().collect(Collectors.toMap(Trade::getOutTradeNo, Function.identity()));
        orderInfos.forEach(orderInfo -> {
            Trade trade = map.get(orderInfo.getOrderCode());
            if(trade!=null){
                orderInfo.setTransactionId(trade.getTransactionId());
                orderInfo.setTrade(trade);
            }
        });
    }


    /**
     * @description: 订单组装开关
     * @author: lig
     * @date: 2024/3/8
     */
    @Data
    public static class OrderInfoPlug {
        private boolean orderExt = false;
        private boolean ticket = false;
        private boolean userInfo = false;
        private boolean massageService = false;
        private boolean shop = false;
        private boolean massagist = false;
        private boolean evaluate = false;
        private boolean profit = false;
        private boolean refumd = false;
        private boolean trade  = false;

        OrderInfoPlug() {
        }

        public static OrderInfoPlug base() {
            OrderInfoPlug plug = new OrderInfoPlug();
            plug.setOrderExt(true);
            plug.setUserInfo(true);
            plug.setMassageService(true);
            plug.setShop(true);
            plug.setMassagist(true);
            plug.setEvaluate(false);
            plug.setTrade(false);
            return plug;
        }

        public static OrderInfoPlug empty() {
            return new OrderInfoPlug();
        }
    }

}
